package com.atguigu.gmall.product.controller;

import java.util.concurrent.*;

/**
 * @Author atguigu-mqx
 * @Description TODO
 * @Date 2023/5/16 14:11
 * @Version 1.0
 */
public class CompletableFutureDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //  runAsync() - 复制小括号，写死右箭头，落地大括号
        //        CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(() -> {
        //            System.out.println("我是无返回值的线程.");
        //        });
        //        //  {}:get(); 方法的实现
        //        CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {
        //            System.out.println("我是有返回值的线程.");
        //            return 1024;
        //        });
        //        System.out.println(integerCompletableFuture.get());

        //         串行化
        //        CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {
        //                    System.out.println("我是有返回值的线程.");
        ////                    int i = 1 / 0;
        //                    return 1024;
        //                }).thenApply((f) -> {
        //                    System.out.println(f); // 1024
        //                    return f * 2; // 2048
        //                })
        //                .whenComplete((t, u) -> {
        //                    System.out.println("t" + t); // t: 接收上一个的结果.    2048
        //                    System.out.println("u" + u); // u: 异常信息
        //                }).exceptionally((t) -> {
        //                    System.out.println(t); // 获取异常信息
        //                    return 404; //  异常了给一个返回值
        //                });
        //        System.out.println(integerCompletableFuture.get());

        //      创建线程池 为什么不能使用工具类创建?  阻塞队列或最大线程数都是Integer.MAX_VALUE; OOM;
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
               5, // cpu:n+1 io:2n 内核数据 n= 4;
                10,
                3,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(10)
        );
        //      并行化：
        CompletableFuture<String> completableFutureA = CompletableFuture.supplyAsync(() -> "hello");

        CompletableFuture<Void> completableFutureB = completableFutureA.thenAcceptAsync(s -> {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            //  s = hello;
            System.out.println(s + ":\tB");
        },threadPoolExecutor);
        CompletableFuture<Void> completableFutureC = completableFutureA.thenAcceptAsync(s -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            //  s = hello;
            System.out.println(s + ":\tC");
        },threadPoolExecutor);

        System.out.println(completableFutureB.get());
        System.out.println(completableFutureC.get());

    }
}
